﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Compression;

namespace ConsoleApplication
{
    class GzipStreamLineReader
    {
        private GZipStream _stream;
        private Queue<string> _lines;
        private string _incompleteLine;
        private byte[] _buffer;
        private int _buffSize;

        public GzipStreamLineReader(GZipStream stream)
        {
            _stream = stream;

             _buffer = new byte[32 * 1024];

            _lines = new Queue<string>();
        }

        public String GetNextLine()
        {
            if (_lines.Count == 0)
                advancePosition();

            if (_lines.Count == 0)
                return null;

            return _lines.Dequeue();
        }

        private void advancePosition()
        {
            _buffSize = _stream.Read(_buffer, 0, _buffer.Length);

            String fullString = ASCIIEncoding.ASCII.GetString(_buffer, 0, _buffSize);

            if (fullString.Length == 0)
                return;

            bool weActuallyEndedWithANewlineWow = false;
            if (fullString[fullString.Length-1] == '\n' || fullString[fullString.Length-1] == '\r')
                weActuallyEndedWithANewlineWow = true;

            String[] lineSet = fullString.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);

            if (!string.IsNullOrEmpty(_incompleteLine) && lineSet.Length > 0)
            {
                lineSet[0] = string.Concat(_incompleteLine, lineSet[0]);
            }

            for (int i = 0; i < lineSet.Length-(weActuallyEndedWithANewlineWow?0:1); i++)
            {
                _lines.Enqueue(lineSet[i]);
            }

            if (weActuallyEndedWithANewlineWow && lineSet.Length - 1 > 0)
                _incompleteLine = lineSet[lineSet.Length - 1];
        }
    }
}
